////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); All rights reserved. //
//                                                                                //
// Redistribution  and  use  in  source   and  binary  forms,   with  or  without //
// modification,  are permitted  provided that  the following conditions are met: //
//   * Redistributions   of  source   code  must  retain   the   above  copyright //
//     notice,  this   list   of   conditions   and   the  following  disclaimer. //
//   * Redistributions  in  binary  form  must  reproduce  the  above   copyright //
//     notice, this  list  of  conditions  and the  following  disclaimer in  the //
//     documentation and/or  other  materials  provided  with  the  distribution. //
//   * Neither the name of the University of British Columbia (UBC) nor the names //
//     of   its   contributors  may  be  used  to  endorse  or   promote products //
//     derived from  this  software without  specific  prior  written permission. //
//                                                                                //
// THIS  SOFTWARE IS  PROVIDED  BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
// AND  ANY EXPRESS  OR IMPLIED WARRANTIES,  INCLUDING,  BUT NOT LIMITED TO,  THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED.  IN NO  EVENT SHALL University of British Columbia (UBC) BE LIABLE //
// FOR ANY DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL //
// DAMAGES  (INCLUDING,  BUT NOT LIMITED TO,  PROCUREMENT OF  SUBSTITUTE GOODS OR //
// SERVICES;  LOSS OF USE,  DATA,  OR PROFITS;  OR BUSINESS INTERRUPTION) HOWEVER //
// CAUSED AND ON ANY THEORY OF LIABILITY,  WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
// OF  THIS SOFTWARE,  EVEN  IF  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGE. //
////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////
//           smpram_wrp.v: Switchable multiported-RAM synthesis wrapper           //
//                                                                                //
//    Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com)    //
// Switchable SRAM-based Multi-ported RAMs; University of British Columbia, 2014  //
////////////////////////////////////////////////////////////////////////////////////

`include "utils.vh"

// configure architectural parameters
`include "config.vh"

module smpram_wrp
 #(  parameter MEMD = `MEMD, // memory depth
     parameter DATW = `DATW, // data width
     parameter nRPN = `nRPN, // number of reading ports / normal mode
     parameter nWPN = `nWPN, // number of writing ports / normal mode
     parameter nRPE = `nRPE, // number of reading ports / extended mode
     parameter nWPE = `nWPE, // number of writing ports / extended mode
     parameter ARCH = `ARCH, // architecture: REG, XOR, LVTREG, LVTBIN, LVT1HT, AUTO
     parameter BYPS = `BYPS, // Bypassing type: NON, WAW, RAW, RDW
     parameter FILE = ""     // initialization file, optional
  )( input                              clk  ,  // clock
     input                              ext  ,  // extended mode
     input       [nWPN-1:0            ] WEnb ,  // write enable for each writing port
     input       [`log2(MEMD)*nWPN-1:0] WAddr,  // write addresses - packed from nWPN write ports
     input       [DATW       *nWPN-1:0] WData,  // write data - packed from nWPN read ports
     input       [`log2(MEMD)*nRPE-1:0] RAddr,  // read  addresses - packed from nRPE  read  ports
     output wire [DATW       *nRPE-1:0] RData); // read  data - packed from nRPE read ports


  // instantiate a multiported-RAM
  smpram #( .MEMD  (MEMD ),  // positive integer: memory depth
            .DATW  (DATW ),  // positive integer: data width
            .nRPN  (nRPN ),  // number of reading ports / normal mode
            .nWPN  (nWPN ),  // number of writing ports / normal mode
            .nRPE  (nRPE ),  // number of reading ports / extended mode
            .nWPE  (nWPE ),  // number of writing ports / extended mode
            .ARCH  (ARCH ),  // text: multi-port RAM implementation type: "AUTO", "REG", "XOR", "LVTREG", "LVTBIN", or "LVT1HT"
                                //   AUTO  : Choose automatically based on the design parameters
                                //   REG   : Register-based multi-ported RAM
                                //   XOR   : XOR-based nulti-ported RAM  
                                //   LVTREG: Register-based LVT multi-ported RAM
                                //   LVTBIN: Binary-coded I-LVT-based multi-ported RAM
                                //   LVT1HT: Onehot-coded I-LVT-based multi-ported RAM
            .BYPS  (BYPS ),  // text: Bypassing type: "NON", "WAW", "RAW", or "RDW"
                                //   WAW: Allow Write-After-Write (need to bypass feedback ram)
                                //   RAW: New data for Read-after-Write (need to bypass output ram)
                                //   RDW: New data for Read-During-Write
            .FILE  (""   ))  // text: initializtion file, optional
  smprami ( .clk   (clk  ),  // clock
            .ext   (ext  ),  // extended mode
            .WEnb  (WEnb ),  // write enable for each writing port             - input : [nWPN-1:0            ]
            .WAddr (WAddr),  // write addresses - packed from nWPN write ports - input : [`log2(MEMD)*nWPN-1:0]
            .WData (WData),  // write data      - packed from nWPN read  ports - input : [DATW       *nWPN-1:0]
            .RAddr (RAddr),  // read  addresses - packed from nRPE read  ports - input : [`log2(MEMD)*nRPE-1:0]
            .RData (RData)); // read  data      - packed from nRPE read  ports - output: [DATW       *nRPE-1:0]

endmodule

